package com.ruoyi.asset.tool.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.asset.tool.domain.Tool;
import com.ruoyi.asset.tool.domain.bo.ToolSearchBo;
import com.ruoyi.asset.tool.domain.bo.ToolStatisticsBo;
import com.ruoyi.asset.tool.domain.vo.ToolVo;
import com.ruoyi.asset.tool.mapper.ToolMapper;
import com.ruoyi.asset.tool.service.IToolService;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.tools.excel.MyExcelUtil;
import com.ruoyi.common.tools.excel.base.MyExcelResult;
import com.ruoyi.common.tools.excel.listener.asset.ToolExcelListener;
import com.ruoyi.common.tools.utils.SerialGenerator;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.service.ISysDictDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

@RequiredArgsConstructor
@Service
public class ToolService implements IToolService {

    private final ToolMapper baseMapper;

    private ISysDictDataService sysDictDataService = SpringUtils.getBean(ISysDictDataService.class);

    @Override
    public Boolean batchInsertOrUpdate(List<Tool> voList) {
        return this.baseMapper.insertOrUpdateBatch(voList);
    }

    @Override
    public List<String> importExcel(String excelUrl, String serviceType) {
        List<String> errorMsgList = new ArrayList<>();
        // 生成批次号
        final String batchNo = SerialGenerator.generator.nextId();

        // excel 处理
        MyExcelResult<ToolVo> excelResult = MyExcelUtil.getImportExcelData(batchNo, excelUrl,
            new ToolExcelListener(serviceType), ToolVo.class, true);

        if (null == excelResult) {
            errorMsgList.add("未获取到要处理的数据");

            return null;
        }

        /**
         *  有解析失败就直接返回错误信息
         */
        if(!excelResult.getErrorList().isEmpty()) {
            return excelResult.getErrorList();
        }

        if (!excelResult.getList().isEmpty()) {
            List<Tool> list = new ArrayList<>();

            AtomicInteger row = new AtomicInteger(0);

            excelResult.getList().forEach(e -> {
                int currentRow = row.incrementAndGet();
                if (e.getDataCheckResult().isSucess()) {
                    Tool tool = new Tool();
                    BeanCopyUtils.copy(e, tool);
                    Tool oldTool = getVoByCodeAndNameAndType(tool.getToolCode(), tool.getToolName(),
                        tool.getToolType(), tool.getServiceType());
                    if(oldTool != null) {
                        tool.setId(oldTool.getId());
                    }

                    /**
                     *  如果各行数据校验通过，再遍历检查是否数据重复
                     */
                    if(excelResult.getValidateList().isEmpty()) {
                        AtomicInteger count = new AtomicInteger(0);
                        list.stream().anyMatch(f -> {
                            int currentCount = count.incrementAndGet();
                            if(f.getToolCode().equals(tool.getToolCode()) && f.getToolName().equals(tool.getToolName())
                                && f.getToolType().equals(tool.getToolType()) && f.getServiceType().equals(tool.getServiceType())) {
                                errorMsgList.add(String.format("第 %d 行数据检查失败，失败原因：与第%d行数据重复", currentRow, currentCount));
                                return true;
                            }
                            return false;
                        });
                    }

                    list.add(tool);
                } else {
                    errorMsgList.add(String.format("第 %d 行数据检查失败，失败原因：%s", currentRow, e.getDataCheckResult().getMsg()));
                }
            });

            if (errorMsgList.isEmpty()) {
                batchInsertOrUpdate(list);
            }
        }

        return errorMsgList;
    }

    private Tool getVoByCodeAndNameAndType(String code, String name, String type, String serviceType) {
        LambdaQueryWrapper<Tool> lqw = Wrappers.lambdaQuery();

        lqw.eq(Tool::getToolCode, code);
        lqw.eq(Tool::getToolName, name);
        lqw.eq(Tool::getToolType, type);
        lqw.eq(Tool::getServiceType, serviceType);
        lqw.eq(Tool::getDelFlag, 0);

        List<Tool> list = baseMapper.selectList(lqw);

        return list.isEmpty() ? null : list.get(0);
    }

    /**
     * 批量删除清扫保洁
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 查询作业人员列表
     */
    @Override
    public TableDataInfo<ToolVo> queryPageList(ToolSearchBo searchBo, PageQuery pageQuery) {
        Page<ToolVo> result = baseMapper.selectToolPage(pageQuery.build(), searchBo);
        List<ToolVo> list = new ArrayList<>();
        result.getRecords().forEach(e -> {
            ToolVo toolVo = new ToolVo();
            BeanCopyUtils.copy(e, toolVo);
            String toolType = sysDictDataService.selectDictLabel("assetmanage_tool_type", toolVo.getToolType());
            String serviceType = sysDictDataService.selectDictLabel("erecord_service_type", toolVo.getServiceType());
            if(!StringUtils.isBlank(toolType)) {
                toolVo.setToolType(toolType);
            }
            if(!StringUtils.isBlank(serviceType)) {
                toolVo.setServiceType(serviceType);
            }
            list.add(toolVo);
        });
        result.setRecords(list);
        return TableDataInfo.build(result);
    }


    @Override
    public List<ToolVo> exportTool(ToolSearchBo searchBo) {
        List<ToolVo> list = new ArrayList<>();

        baseMapper.exportTool(searchBo).forEach(e -> {
            ToolVo toolVo = new ToolVo();
            BeanCopyUtils.copy(e, toolVo);
            String dictLabel = sysDictDataService.selectDictLabel("assetmanage_tool_type", toolVo.getToolType());
            if(!StringUtils.isBlank(dictLabel)) {
                toolVo.setToolType(dictLabel);
            }
            list.add(toolVo);
        });
        return list;
    }

	@Override
	public Map statisticsToolByServiceType(String serviceType) {
		return baseMapper.statisticsToolByServiceType(serviceType);
	}

    @Override
    public ToolStatisticsBo getCountByServiceType(String serviceType) {
        ToolStatisticsBo toolStatisticsBo = new ToolStatisticsBo();
        Integer toolCount = baseMapper.selectToolCount(serviceType, 2);
        toolStatisticsBo.setToolCount(toolCount);
        Integer vehicleCount = baseMapper.selectToolCount(serviceType, 1);
        toolStatisticsBo.setVehicleCount(vehicleCount);
        return toolStatisticsBo;
    }

    @Override
    public ToolStatisticsBo getCountByServiceTypeAndCommunity(String serviceType,String community) {
        ToolStatisticsBo toolStatisticsBo = new ToolStatisticsBo();
        Integer toolCountByCommunity = baseMapper.selectToolCountByCommunity(serviceType, 2,community);
        toolStatisticsBo.setToolCount(toolCountByCommunity);
        Integer vehicleCountByCommunity = baseMapper.selectToolCountByCommunity(serviceType, 1,community);
        toolStatisticsBo.setVehicleCount(vehicleCountByCommunity);
        return toolStatisticsBo;
    }

    @Override
    public ToolStatisticsBo getCommunityByServiceTypeAndDate(String serviceType, String community, String date) {
        ToolStatisticsBo toolStatisticsBo = new ToolStatisticsBo();
        Integer toolCount = baseMapper.selectCommunityByServiceTypeAndDate(serviceType, 2, community, date);
        toolStatisticsBo.setToolCount(toolCount);
        Integer vehicleCount = baseMapper.selectCommunityByServiceTypeAndDate(serviceType, 1, community, date);
        toolStatisticsBo.setVehicleCount(vehicleCount);
        return toolStatisticsBo;
    }
}
